package com.searchengine.service.impl;

import com.searchengine.entity.KeywordWeight;
import com.searchengine.entity.PaymentRecord;
import com.searchengine.entity.User;
import com.searchengine.repository.KeywordWeightRepository;
import com.searchengine.repository.PaymentRecordRepository;
import com.searchengine.repository.UserRepository;
import com.searchengine.service.KeywordWeightService;
import com.searchengine.service.PaymentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;

/**
 * 支付服务实现类
 */
@Service
public class PaymentServiceImpl implements PaymentService {

    @Autowired
    private PaymentRecordRepository paymentRecordRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private KeywordWeightService keywordWeightService;

    @Autowired
    private KeywordWeightRepository keywordWeightRepository;

    @Value("${alipay.appid}")
    private String alipayAppId;

    @Value("${alipay.private_key}")
    private String alipayPrivateKey;

    @Value("${alipay.public_key}")
    private String alipayPublicKey;

    @Value("${alipay.notify_url}")
    private String alipayNotifyUrl;

    // 单价（每天每权重单位的价格）
    private static final BigDecimal UNIT_PRICE = new BigDecimal(10);

    @Override
    @Transactional
    public PaymentRecord createPaymentOrder(Long userId, String keyword, BigDecimal weight, Integer durationDays) {
        // 验证用户是否存在
        Optional<User> userOptional = userRepository.findById(userId);
        if (!userOptional.isPresent()) {
            throw new RuntimeException("用户不存在");
        }

        // 验证参数
        if (weight.compareTo(BigDecimal.ZERO) <= 0) {
            throw new RuntimeException("权重值必须大于0");
        }

        if (durationDays < 1) {
            throw new RuntimeException("持续天数必须大于0");
        }

        // 计算金额
        BigDecimal amount = calculateAmount(weight, durationDays);

        // 创建支付记录
        PaymentRecord paymentRecord = new PaymentRecord();
        paymentRecord.setUser(userOptional.get());
        paymentRecord.setOrderNo(generateOrderNo());
        paymentRecord.setAmount(amount);
        paymentRecord.setStatus(0); // 0: 待支付

        // 保存支付记录
        paymentRecord = paymentRecordRepository.save(paymentRecord);

        // 创建关键词权重占位记录
        Date now = new Date();
        Date endTime = new Date(now.getTime() + durationDays * 24 * 60 * 60 * 1000L);
        
        KeywordWeight keywordWeight = new KeywordWeight();
        keywordWeight.setUser(userOptional.get());
        keywordWeight.setKeyword(keyword);
        keywordWeight.setWeight(weight);
        keywordWeight.setStartTime(now);
        keywordWeight.setEndTime(endTime);
        
        keywordWeight = keywordWeightRepository.save(keywordWeight);
        
        // 关联支付记录和关键词权重
        paymentRecord.setKeywordWeight(keywordWeight);
        paymentRecord = paymentRecordRepository.save(paymentRecord);

        return paymentRecord;
    }

    @Override
    public String generatePaymentUrl(String orderNo, BigDecimal amount, String subject) {
        // 这里是生成支付宝支付URL的逻辑
        // 实际应用中需要使用支付宝SDK生成支付链接
        // 目前只是返回示例URL
        return "https://openapi.alipaydev.com/gateway.do?app_id=" + alipayAppId + "\u0026out_trade_no=" + orderNo + "\u0026total_amount=" + amount + "\u0026subject=" + subject + "\u0026notify_url=" + alipayNotifyUrl;
    }

    @Override
    @Transactional
    public boolean handlePaymentCallback(Map<String, String> params) {
        // 验证签名
        String sign = params.get("sign");
        if (!verifyPaymentSign(params, sign)) {
            return false;
        }

        // 获取订单号和交易号
        String orderNo = params.get("out_trade_no");
        String tradeNo = params.get("trade_no");
        String tradeStatus = params.get("trade_status");

        // 查询订单
        Optional<PaymentRecord> paymentOptional = paymentRecordRepository.findByOrderNo(orderNo);
        if (!paymentOptional.isPresent()) {
            return false;
        }

        PaymentRecord paymentRecord = paymentOptional.get();

        // 检查订单状态
        if (paymentRecord.getStatus() == 1) { // 已经支付成功
            return true;
        }

        // 处理支付结果
        if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {
            // 更新支付记录
            paymentRecord.setStatus(1); // 支付成功
            paymentRecord.setTradeNo(tradeNo);
            paymentRecord.setPaidAt(new Date());
            paymentRecordRepository.save(paymentRecord);
            
            // 这里可以添加支付成功后的业务逻辑，比如激活关键词权重等
            
            return true;
        } else {
            // 更新为支付失败
            paymentRecord.setStatus(2); // 支付失败
            paymentRecordRepository.save(paymentRecord);
            return false;
        }
    }

    @Override
    public PaymentRecord queryOrderStatus(String orderNo) {
        Optional<PaymentRecord> paymentOptional = paymentRecordRepository.findByOrderNo(orderNo);
        if (!paymentOptional.isPresent()) {
            throw new RuntimeException("订单不存在");
        }
        return paymentOptional.get();
    }

    @Override
    @Transactional
    public boolean closeOrder(String orderNo) {
        Optional<PaymentRecord> paymentOptional = paymentRecordRepository.findByOrderNo(orderNo);
        if (!paymentOptional.isPresent()) {
            return false;
        }

        PaymentRecord paymentRecord = paymentOptional.get();

        // 只有待支付的订单可以关闭
        if (paymentRecord.getStatus() != 0) {
            return false;
        }

        // 更新订单状态
        paymentRecord.setStatus(2); // 支付失败
        paymentRecordRepository.save(paymentRecord);

        // 删除关联的关键词权重记录
        if (paymentRecord.getKeywordWeight() != null) {
            keywordWeightRepository.deleteById(paymentRecord.getKeywordWeight().getId());
        }

        return true;
    }

    @Override
    public List<PaymentRecord> getUserPaymentRecords(Long userId) {
        return paymentRecordRepository.findByUserId(userId);
    }

    @Override
    public BigDecimal calculateAmount(BigDecimal weight, Integer durationDays) {
        // 金额 = 权重值 * 天数 * 单价
        return weight.multiply(new BigDecimal(durationDays)).multiply(UNIT_PRICE);
    }

    @Override
    public boolean verifyPaymentSign(Map<String, String> params, String sign) {
        // 这里是验证支付签名的逻辑
        // 实际应用中需要使用支付宝SDK进行签名验证
        // 目前只是返回示例结果
        return true;
    }

    /**
     * 生成订单号
     * @return 订单号
     */
    private String generateOrderNo() {
        return "ORDER_" + System.currentTimeMillis() + "_" + UUID.randomUUID().toString().substring(0, 8).toUpperCase();
    }
}